home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / proc / mem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  5.8 KB  |  283 lines

  1. /*
  2.  *  linux/fs/proc/mem.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. #include <linux/types.h>
  8. #include <linux/errno.h>
  9. #include <linux/sched.h>
  10. #include <linux/kernel.h>
  11.  
  12. #include <asm/segment.h>
  13. #include <asm/io.h>
  14.  
  15. /*
  16.  * mem_write isn't really a good idea right now. It needs
  17.  * to check a lot more: if the process we try to write to 
  18.  * dies in the middle right now, mem_write will overwrite
  19.  * kernel memory.. This disables it altogether.
  20.  */
  21. #define mem_write NULL
  22.  
  23. #if defined(__i386__)
  24. static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
  25. {
  26.     unsigned long addr, pid, cr3;
  27.     char *tmp;
  28.     unsigned long pte, page;
  29.     int i;
  30.  
  31.     if (count < 0)
  32.         return -EINVAL;
  33.     pid = inode->i_ino;
  34.     pid >>= 16;
  35.     cr3 = 0;
  36.     for (i = 1 ; i < NR_TASKS ; i++)
  37.         if (task[i] && task[i]->pid == pid) {
  38.             cr3 = task[i]->tss.cr3;
  39.             break;
  40.         }
  41.     if (!cr3)
  42.         return -EACCES;
  43.     addr = file->f_pos;
  44.     tmp = buf;
  45.     while (count > 0) {
  46.         if (current->signal & ~current->blocked)
  47.             break;
  48.         pte = *PAGE_DIR_OFFSET(cr3,addr);
  49.         if (!(pte & PAGE_PRESENT))
  50.             break;
  51.         pte &= PAGE_MASK;
  52.         pte += PAGE_PTR(addr);
  53.         page = *(unsigned long *) pte;
  54.         if (!(page & 1))
  55.             break;
  56.         page &= PAGE_MASK;
  57.         page += addr & ~PAGE_MASK;
  58.         i = PAGE_SIZE-(addr & ~PAGE_MASK);
  59.         if (i > count)
  60.             i = count;
  61.         memcpy_tofs(tmp,(void *) page,i);
  62.         addr += i;
  63.         tmp += i;
  64.         count -= i;
  65.     }
  66.     file->f_pos = addr;
  67.     return tmp-buf;
  68. }
  69.  
  70. #ifndef mem_write
  71.  
  72. static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
  73. {
  74.     unsigned long addr, pid, cr3;
  75.     char *tmp;
  76.     unsigned long pte, page;
  77.     int i;
  78.  
  79.     if (count < 0)
  80.         return -EINVAL;
  81.     addr = file->f_pos;
  82.     pid = inode->i_ino;
  83.     pid >>= 16;
  84.     cr3 = 0;
  85.     for (i = 1 ; i < NR_TASKS ; i++)
  86.         if (task[i] && task[i]->pid == pid) {
  87.             cr3 = task[i]->tss.cr3;
  88.             break;
  89.         }
  90.     if (!cr3)
  91.         return -EACCES;
  92.     tmp = buf;
  93.     while (count > 0) {
  94.         if (current->signal & ~current->blocked)
  95.             break;
  96.         pte = *PAGE_DIR_OFFSET(cr3,addr);
  97.         if (!(pte & PAGE_PRESENT))
  98.             break;
  99.         pte &= PAGE_MASK;
  100.         pte += PAGE_PTR(addr);
  101.         page = *(unsigned long *) pte;
  102.         if (!(page & PAGE_PRESENT))
  103.             break;
  104.         if (!(page & 2)) {
  105.             do_wp_page(0,addr,current,0);
  106.             continue;
  107.         }
  108.         page &= PAGE_MASK;
  109.         page += addr & ~PAGE_MASK;
  110.         i = PAGE_SIZE-(addr & ~PAGE_MASK);
  111.         if (i > count)
  112.             i = count;
  113.         memcpy_fromfs((void *) page,tmp,i);
  114.         addr += i;
  115.         tmp += i;
  116.         count -= i;
  117.     }
  118.     file->f_pos = addr;
  119.     if (tmp != buf)
  120.         return tmp-buf;
  121.     if (current->signal & ~current->blocked)
  122.         return -ERESTARTSYS;
  123.     return 0;
  124. }
  125.  
  126. #endif
  127. #elif defined(__mc68000__)
  128. static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
  129. {
  130.     unsigned long addr, pid, *rootp, *ptrp;
  131.     char *tmp;
  132.     unsigned long pte, page;
  133.     int i;
  134.  
  135.     if (count < 0)
  136.         return -EINVAL;
  137.     pid = inode->i_ino;
  138.     pid >>= 16;
  139.     rootp = NULL;
  140.     for (i = 1 ; i < NR_TASKS ; i++)
  141.         if (task[i] && task[i]->pid == pid) {
  142.             rootp = task[i]->tss.pagedir_v;
  143.             break;
  144.         }
  145.     if (!rootp)
  146.         return -EACCES;
  147.     addr = file->f_pos;
  148.     tmp = buf;
  149.     while (count > 0) {
  150.         if (current->signal & ~current->blocked)
  151.             break;
  152.         pte = rootp[L1_INDEX(addr)];
  153.         if (!(pte & PAGE_TABLE))
  154.             break;
  155.         ptrp = (unsigned long *)PTOV(pte & TABLE_MASK);
  156.         pte = ptrp[L2_INDEX(addr)];
  157.         if (!(pte & PAGE_TABLE))
  158.             break;
  159.         pte = PTOV(pte & PAGE_MASK);
  160.         pte += PAGE_PTR(addr);
  161.         page = *(unsigned long *) pte;
  162.         if (!(page & PAGE_PRESENT))
  163.             break;
  164.         page = PTOV(page & PAGE_MASK);
  165.         page += addr & ~PAGE_MASK;
  166.         i = PAGE_SIZE-(addr & ~PAGE_MASK);
  167.         if (i > count)
  168.             i = count;
  169.         memcpy_tofs(tmp,(void *) page,i);
  170.         addr += i;
  171.         tmp += i;
  172.         count -= i;
  173.     }
  174.     file->f_pos = addr;
  175.     return tmp-buf;
  176. }
  177.  
  178. #ifndef mem_write
  179.  
  180. static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
  181. {
  182.     unsigned long addr, pid, *rootp, *ptrp;
  183.     char *tmp;
  184.     unsigned long pte, page;
  185.     int i;
  186.  
  187.     if (count < 0)
  188.         return -EINVAL;
  189.     addr = file->f_pos;
  190.     pid = inode->i_ino;
  191.     pid >>= 16;
  192.     rootp = NULL;
  193.     for (i = 1 ; i < NR_TASKS ; i++)
  194.         if (task[i] && task[i]->pid == pid) {
  195.             rootp = task[i]->tss.pagedir_v;
  196.             break;
  197.         }
  198.     if (!rootp)
  199.         return -EACCES;
  200.     tmp = buf;
  201.     while (count > 0) {
  202.         if (current->signal & ~current->blocked)
  203.             break;
  204.         pte = rootp[L1_INDEX(addr)];
  205.         if (!(pte & PAGE_TABLE))
  206.             break;
  207.         ptrp = (unsigned long *)PTOV(pte & TABLE_MASK);
  208.         pte = ptrp[L2_INDEX(addr)];
  209.         if (!(pte & PAGE_TABLE))
  210.             break;
  211.         pte = PTOV(pte & PAGE_MASK);
  212.         pte += PAGE_PTR(addr);
  213.         page = *(unsigned long *) pte;
  214.         if (!(page & (PAGE_COW|PAGE_ACCESSED)) ||
  215.             !PAGE_IS_RW(page)) {
  216.             do_wp_page(0,addr,current,0);
  217.             continue;
  218.         }
  219.         page = PTOV(page & PAGE_MASK);
  220.         page += addr & ~PAGE_MASK;
  221.         i = PAGE_SIZE-(addr & ~PAGE_MASK);
  222.         if (i > count)
  223.             i = count;
  224.         memcpy_fromfs((void *) page,tmp,i);
  225.         addr += i;
  226.         tmp += i;
  227.         count -= i;
  228.     }
  229.     file->f_pos = addr;
  230.     if (tmp != buf)
  231.         return tmp-buf;
  232.     if (current->signal & ~current->blocked)
  233.         return -ERESTARTSYS;
  234.     return 0;
  235. }
  236. #endif /* mem_write */
  237. #endif /* mc68000 */
  238.  
  239. static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
  240. {
  241.     switch (orig) {
  242.         case 0:
  243.             file->f_pos = offset;
  244.             return file->f_pos;
  245.         case 1:
  246.             file->f_pos += offset;
  247.             return file->f_pos;
  248.         default:
  249.             return -EINVAL;
  250.     }
  251. }
  252.  
  253. static struct file_operations proc_mem_operations = {
  254.     mem_lseek,
  255.     mem_read,
  256.     mem_write,
  257.     NULL,        /* mem_readdir */
  258.     NULL,        /* mem_select */
  259.     NULL,        /* mem_ioctl */
  260.     NULL,        /* mmap */
  261.     NULL,        /* no special open code */
  262.     NULL,        /* no special release code */
  263.     NULL        /* can't fsync */
  264. };
  265.  
  266. struct inode_operations proc_mem_inode_operations = {
  267.     &proc_mem_operations,    /* default base directory file-ops */
  268.     NULL,            /* create */
  269.     NULL,            /* lookup */
  270.     NULL,            /* link */
  271.     NULL,            /* unlink */
  272.     NULL,            /* symlink */
  273.     NULL,            /* mkdir */
  274.     NULL,            /* rmdir */
  275.     NULL,            /* mknod */
  276.     NULL,            /* rename */
  277.     NULL,            /* readlink */
  278.     NULL,            /* follow_link */
  279.     NULL,            /* bmap */
  280.     NULL,            /* truncate */
  281.     NULL            /* permission */
  282. };
  283.